﻿Imports XL.Common
Imports XL.Common.Utils
Imports AssetVisionXAuto.Facade
Imports System.Collections
Imports System.Data
Imports System.Linq

Namespace Facade

    Public Class OpBizInventory

        'Public Shared Function TransactDtlListReplacePlan(ByVal taskList As AssetVisionXAuto.FTs.FT_T_AV_INVENTORY_TASK, ByVal generateReplace As Boolean) As Integer

        '    Dim transactCount As Integer = 0

        '    If taskList.Count = 0 Then
        '        Return transactCount
        '    End If

        '    Dim remarkBuilder As New LineStrBuilder
        '    Dim result As Integer

        '    For Each taskRow As AssetVisionXAuto.FTs.FT_T_AV_INVENTORY_TASKRow In taskList

        '        remarkBuilder.Clear()
        '        result = Facade.OpBizInventory.TransactresultListReplacePlan(taskRow, generateReplace)
        '        If result > 0 Then
        '            remarkBuilder.AppendFormat("{0}条有待处理", result)
        '        End If
        '        taskRow.ROW_REMARK = remarkBuilder.ToString
        '    Next

        '    Return transactCount

        'End Function


        Public Shared Sub GenerateAutoInventoryPlans()

            Dim deptConfigList As New AssetVisionXAuto.FTs.FT_S_AV_ASA_DEPT_CONFIG
            AssetVisionXAuto.Facade.AfBizConfig.FillFT_S_AV_ASA_DEPT_CONFIG( _
                Nothing, _
                deptConfigList)

            For Each deptConfigRow As AssetVisionXAuto.FTs.FT_S_AV_ASA_DEPT_CONFIGRow In deptConfigList
                Facade.OpBizInventory.GenerateAutoInventoryPlanAccordingInterval( _
                    deptConfigRow, _
                    False)
            Next
        End Sub


        Public Shared Sub GenerateAutoInventoryPlanAccordingInterval( _
            ByVal asaDepConfigtRow As AssetVisionXAuto.FTs.FT_S_AV_ASA_DEPT_CONFIGRow, _
            Optional ByVal fillConfigRowSEntityOnly As Boolean = False)

            If asaDepConfigtRow.AUTO_INVENTORY_PLAN_NEEDED = False OrElse _
                asaDepConfigtRow.AUTO_INVENTORY_PLAN_INTERVAL = 0 Then
                Return
            End If

            Dim departmentRowSEntity As New AssetVisionXAuto.FTs.FT_M_AV_DEPARTMENTRowSEntity
            Dim locationList As New AssetVisionXAuto.FTs.FT_M_AV_LOCATION

            Facade.OpBizMaster.FillAddressAloneDepartmentLocationListByStaffID( _
                String.Empty, _
                asaDepConfigtRow.DEPARTMENT_ID, _
                departmentRowSEntity, _
                locationList)


            '属于管辖内的所有地点标识号
            Dim locationRow As AssetVisionXAuto.FTs.FT_M_AV_LOCATIONRow
            Dim chargingLocationIDs As New ArrayList
            For Each locationRow In locationList
                chargingLocationIDs.Add(locationRow.LOCATION_ID)
            Next

            Dim coveredTaskCondition As New AssetVisionXAuto.Facade.AfXV.ConditionOfXV_T_AV_INVENTORY_TASK(XL.DB.Utils.Condition.LogicOperators.Logic_And)
            coveredTaskCondition.Add(AfXV.XV_T_AV_INVENTORY_TASKColumns.LOCATION_IDColumn, True, chargingLocationIDs)
            coveredTaskCondition.Add(AfXV.XV_T_AV_INVENTORY_TASKColumns.CREATE_DATEColumn, ">=", asaDepConfigtRow.INVENTORY_COVER_DATE_FROM)
            coveredTaskCondition.Add(AfXV.XV_T_AV_INVENTORY_TASKColumns.CREATE_DATEColumn, ">=", asaDepConfigtRow.INVENTORY_COVER_DATE_TO)
            '在指定时间内任务覆盖到的所有地点标识号
            Dim taskCoveredLocationIDs = AssetVisionXAuto.Facade.AfXV.GetXV_T_AV_INVENTORY_TASK_CVListDistinct( _
                coveredTaskCondition, _
                AfXV.XV_T_AV_INVENTORY_TASKColumns.LOCATION_IDColumn)

            Dim currentPassedDays As Integer = (CommTK.GetSyncServerTime - asaDepConfigtRow.INVENTORY_COVER_DATE_FROM).Days
            Dim coverRangeDays As Integer = (asaDepConfigtRow.INVENTORY_COVER_DATE_TO - asaDepConfigtRow.INVENTORY_COVER_DATE_FROM).Days - 10 '!!!!!!!!!!!!!!!!!!!!!

            '天数覆盖率标准(应达到的)
            Dim dayCoverRate = currentPassedDays / coverRangeDays
            '地点数量覆盖率
            Dim locationCoverRate = taskCoveredLocationIDs.Count / chargingLocationIDs.Count

            If fillConfigRowSEntityOnly = True Then
                asaDepConfigtRow.CHARGING_TOTAL_LOCATION_COUNT = chargingLocationIDs.Count
                asaDepConfigtRow.INVENTORY_COVERED_LOCATION_COUNT = taskCoveredLocationIDs.Count
                asaDepConfigtRow.INVENTORY_COVERED_RATE = CommTK.FInteger(locationCoverRate * 100)

                Return
            End If

            '计算当前地点覆盖率缺口，才能达到天数覆盖率标准
            Dim coverRateShortage = dayCoverRate - locationCoverRate
            If coverRateShortage <= 0 Then
                Return
            End If

            '当前需要新增盘点地点数量
            Dim dueLocationCount = chargingLocationIDs.Count * coverRateShortage

            '从所有地点中去除已经覆盖到的地点
            For Each taskCoveredLocationID As String In taskCoveredLocationIDs
                chargingLocationIDs.Remove(taskCoveredLocationID)
            Next

            Dim planRemark = CommTK.GetTranslatedString("自动盘点计划, 针对^个地点, 当时总剩余^个", chargingLocationIDs.Count, dueLocationCount)

            Dim randomer = New Random(DateTime.Now.Millisecond)
            Dim locationIndex As Integer
            Dim planningLocationIDs As New ArrayList

            Do While dueLocationCount > 0 AndAlso planningLocationIDs.Count < chargingLocationIDs.Count
                locationIndex = randomer.Next(0, chargingLocationIDs.Count)
                planningLocationIDs.Add(DirectCast(chargingLocationIDs(locationIndex), String))
                dueLocationCount -= 1
                chargingLocationIDs.RemoveAt(locationIndex)
            Loop

            '创建盘点计划
            Dim planID = Guid.NewGuid.ToString
            Dim planCode As String = Facade.OpBizInventory.GetAutoGeneratedInventoryPlanCode(departmentRowSEntity)
            Dim planDueDate As DateTime = CommTK.GetEndOfDate(CommTK.GetSyncServerTime.AddDays(asaDepConfigtRow.AUTO_INVENTORY_PLAN_INTERVAL))
            AssetVisionXAuto.Facade.AfBizInventory.CreateT_AV_INVENTORY_PLANInfo( _
                CommTK.GetSyncServerTime, _
                planDueDate, _
                AssetVisionXAuto.Decls.CIVALUE_INVENTORY_PLAN_STATUS_PUBLISHED, _
                planCode, _
                planID, _
                departmentRowSEntity.RUNNER, _
                planRemark)


            '创建属于此计划的明细
            Dim taskList As New AssetVisionXAuto.FTs.FT_T_AV_INVENTORY_TASK
            Dim taskRow As AssetVisionXAuto.FTs.FT_T_AV_INVENTORY_TASKRow
            Dim locationRowSEntity As New AssetVisionXAuto.FTs.FT_M_AV_LOCATIONRowSEntity
            Dim principals As New List(Of String)


            For Each planingLocationID As String In planningLocationIDs

                AssetVisionXAuto.Facade.AfBizMaster.FillM_AV_LOCATIONRowSEntity( _
                    locationRowSEntity, _
                    planingLocationID)

                AssetVisionXAuto.Facade.AfBizMaster.FillM_AV_DEPARTMENTRowSEntity( _
                    departmentRowSEntity, _
                    locationRowSEntity.DEPARTMENT_ID)

                CommTK.WriteTextToFile( _
                    AssetVisionXService.Decls.CENTRAL_INFORM_LOG_FILENAME, _
                    String.Format("Creating auto inventory plan of location <{0}>{1}", locationRowSEntity.LOCATION_CODE, locationRowSEntity.LOCATION_NAME), _
                    True, _
                    String.Empty)

                taskRow = taskList.AddNewT_AV_INVENTORY_TASKRow( _
                    departmentRowSEntity.RUNNER, _
                    False, _
                    String.Empty, _
                    departmentRowSEntity.PRINCIPAL, _
                    100, _
                    CommTK.GetSyncServerTime, _
                    AssetVisionXAuto.Decls.CIVALUE_INVENTORY_STATUS_UNDERWAY, _
                    planingLocationID, _
                    planID, _
                    departmentRowSEntity.PRINCIPAL, _
                    False, _
                    String.Empty, _
                    Guid.NewGuid.ToString())

                If principals.Contains(departmentRowSEntity.PRINCIPAL) = False Then
                    principals.Add(departmentRowSEntity.PRINCIPAL)
                End If

            Next

            AssetVisionXAuto.Facade.AfBizInventory.SaveBatchT_AV_INVENTORY_TASKData(taskList)

            If CommTK.FBoolean(SysInfo.ReadLocalSysInfo(CommDecl.XLSLVN_IS_CENTRAL_INFORMATION_DISTRIBUTER)) = True Then
                Return
            End If

            '抽出所有PlanningLocation, 减小查找地点数据的范围，减少数据库操作
            locationList.Clear()

            Dim locationCondition As New AssetVisionXAuto.Facade.AfBizMaster.ConditionOfM_AV_LOCATION(XL.DB.Utils.Condition.LogicOperators.Logic_And)
            locationCondition.Add(AfBizMaster.M_AV_LOCATIONColumns.LOCATION_IDColumn, True, planningLocationIDs)
            AssetVisionXAuto.Facade.AfBizMaster.FillFT_M_AV_LOCATION(locationCondition, locationList)

            Facade.OpBizInventory.GenerateAutoInventoryInforms(planID)

        End Sub


        Public Shared Sub GenerateAutoInventoryInforms( _
            ByVal planID As String)

            Dim planRow = AssetVisionXAuto.Facade.AfBizInventory.GetT_AV_INVENTORY_PLANRow(planID)
            If IsNothing(planRow) = False Then
                Return
            End If

            Dim taskCondition As New AssetVisionXAuto.Facade.AfXV.ConditionOfXV_T_AV_INVENTORY_TASK(XL.DB.Utils.Condition.LogicOperators.Logic_And)
            taskCondition.Add(AfXV.XV_T_AV_INVENTORY_TASKColumns.PLAN_IDColumn, "=", planID)
            Dim principals = AssetVisionXAuto.Facade.AfXV.GetXV_T_AV_INVENTORY_TASK_CVListDistinct(taskCondition, AfXV.XV_T_AV_INVENTORY_TASKColumns.PRINCIPAL__STAFF_IDColumn)


            Dim principalContenBuilder As New LineStrBuilder
            Dim runnerContenBuilder As New LineStrBuilder
            Dim staffRowSEntity As New AssetVisionXAuto.FTs.FT_M_AV_STAFFRowSEntity
            Dim locationCondition As New AssetVisionXAuto.Facade.AfBizMaster.ConditionOfM_AV_LOCATION(XL.DB.Utils.Condition.LogicOperators.Logic_And)
            Dim taskList As New AssetVisionXAuto.FTs.FT_XV_T_AV_INVENTORY_TASK
            Dim informTitle = String.Format("有新盘点任务, 计划编号为:{0},  预定完成期限:{1:yyyy-MM-dd}", planRow.PLAN_CODE, planRow.DUE_DATE)

            For Each principalID As String In principals

                AssetVisionXAuto.Facade.AfBizMaster.FillM_AV_STAFFRowSEntity(staffRowSEntity, principalID)
                If staffRowSEntity.IsNull OrElse staffRowSEntity.EMAIL.Length = 0 Then
                    Continue For
                End If

                principalContenBuilder.Clear()
                principalContenBuilder.AppendLine("您好, [{0}]{1}, 此次盘点中, 为您分配盘点任务如下: ")
                runnerContenBuilder.AppendLine("为[{0}]{1} 分配盘点任务: ", staffRowSEntity.STAFF_CODE, staffRowSEntity.STAFF_NAME)

                taskCondition.Clear()
                taskCondition.Add(AfXV.XV_T_AV_INVENTORY_TASKColumns.PRINCIPAL__STAFF_IDColumn, "=", principalID)
                AssetVisionXAuto.Facade.AfXV.FillFT_XV_T_AV_INVENTORY_TASK(taskCondition, taskList)

                For Each taskRow As AssetVisionXAuto.FTs.FT_XV_T_AV_INVENTORY_TASKRow In taskList
                    principalContenBuilder.AppendLine("地点: [0]{1}", taskRow.LOCATION_CODE, taskRow.LOCATION_CODE)
                    runnerContenBuilder.AppendLine("地点: [0]{1}", taskRow.LOCATION_CODE, taskRow.LOCATION_CODE)
                Next

                OpSysConfig.CreateInformMessage( _
                    CommTK.GetSyncServerTime, _
                    staffRowSEntity.EMAIL, _
                    informTitle, _
                    principalContenBuilder.ToString, _
                    staffRowSEntity.MOBILE_PHONE, _
                    informTitle, _
                    My.Computer.Name)

            Next

            AssetVisionXAuto.Facade.AfBizMaster.FillM_AV_STAFFRowSEntity(staffRowSEntity, planRow.PLANER)
            If staffRowSEntity.IsNull OrElse staffRowSEntity.EMAIL.Length = 0 Then
                Return
            End If

            OpSysConfig.CreateInformMessage( _
                CommTK.GetSyncServerTime, _
                staffRowSEntity.EMAIL, _
                informTitle, _
                runnerContenBuilder.ToString, _
                staffRowSEntity.MOBILE_PHONE, _
                informTitle, _
                My.Computer.Name)



        End Sub

        Public Shared Function GetAutoGeneratedInventoryPlanCode(ByVal departmentRowSEntity As AssetVisionXAuto.FTs.FT_M_AV_DEPARTMENTRowSEntity) As String

            Dim resultTeplate = String.Format("AUTO{0}{1:yyyyHHdd}", departmentRowSEntity.DEPARTMENT_CODE, CommTK.GetSyncServerTime)
            Dim planCondtion As New AssetVisionXAuto.Facade.AfBizInventory.ConditionOfT_AV_INVENTORY_PLAN(XL.DB.Utils.Condition.LogicOperators.Logic_And)
            Dim planRow As AssetVisionXAuto.FTs.FT_T_AV_INVENTORY_PLANRow

            Dim result = resultTeplate
            Dim conflictCount = 0
            Do
                If conflictCount > 0 Then
                    result = String.Format("{0}_{}", resultTeplate, conflictCount)
                End If

                planCondtion.Clear()
                planCondtion.Add(AfBizInventory.T_AV_INVENTORY_PLANColumns.PLAN_CODEColumn, "=", result)
                planRow = AssetVisionXAuto.Facade.AfBizInventory.GetT_AV_INVENTORY_PLANRow(planCondtion)
                conflictCount += 1
            Loop While IsNothing(planRow) = False

            Return result

        End Function

        Public Shared Sub ReplaceInventoryTask(ByVal taskID As String)

            Dim taskRow As AssetVisionXAuto.FTs.FT_T_AV_INVENTORY_TASKRow = _
                AssetVisionXAuto.Facade.AfBizInventory.GetT_AV_INVENTORY_TASKRow(taskID)

            If taskRow.INVENTORY_STATUS <> AssetVisionXAuto.Decls.CIVALUE_INVENTORY_STATUS_REPLACE_READY Then
                Return
            End If

            Dim resultList As New AssetVisionXAuto.FTs.FT_XV_T_AV_INVENTORY_RESULT
            Dim resultRow As AssetVisionXAuto.FTs.FT_XV_T_AV_INVENTORY_RESULTRow
            Dim resultCondition As New AssetVisionXAuto.Facade.AfXV.ConditionOfXV_T_AV_INVENTORY_RESULT(XL.DB.Utils.Condition.LogicOperators.Logic_And)
            resultCondition.Add(AfXV.XV_T_AV_INVENTORY_RESULTColumns.TASK_IDColumn, "=", taskRow.TASK_ID)
            AssetVisionXAuto.Facade.AfXV.FillFT_XV_T_AV_INVENTORY_RESULT(resultCondition, resultList)

            Dim movingDepartmentAssetLists As New Hashtable
            Dim movingDepartmentAssets As New ArrayList
            Dim maybeLostAssets As New ArrayList

            For Each resultRow In resultList

                Select Case resultRow.INVENTORY_RESULT_TYPE
                    Case AssetVisionXAuto.Decls.CIVALUE_INVENTORY_RESULT_TYPE_REDUNDANCY

                        '盘盈
                        If movingDepartmentAssetLists.ContainsKey(resultRow.CURRENT_DEPARTMENT__DEPARTMENT_ID) = False Then
                            movingDepartmentAssets = New ArrayList
                            movingDepartmentAssetLists.Add(resultRow.CURRENT_DEPARTMENT__DEPARTMENT_ID, movingDepartmentAssets)
                        Else
                            movingDepartmentAssets = CType(movingDepartmentAssetLists.Item(resultRow.CURRENT_DEPARTMENT__DEPARTMENT_ID), ArrayList)
                        End If
                        movingDepartmentAssets.Add(resultRow)

                    Case AssetVisionXAuto.Decls.CIVALUE_INVENTORY_RESULT_TYPE_DEFICIT
                        '盘亏

                        maybeLostAssets.Add(resultRow)

                End Select

            Next

            Dim formID As String
            Dim currentDate As DateTime = OpSysConfig.GetServerTime
            Dim toLocationRow As AssetVisionXAuto.FTs.FT_M_AV_LOCATIONRow
            Dim toDepartmentRow As AssetVisionXAuto.FTs.FT_M_AV_DEPARTMENTRow
            Dim moveDtlList As New AssetVisionXAuto.FTs.FT_H_AV_ASSET_MOVE_DTL
            '生成盘盈移动数据 并执行
            For Each departmentID As String In movingDepartmentAssetLists.Keys

                toLocationRow = AssetVisionXAuto.Facade.AfBizMaster.GetM_AV_LOCATIONRow(taskRow.LOCATION_ID)
                toDepartmentRow = AssetVisionXAuto.Facade.AfBizMaster.GetM_AV_DEPARTMENTRow(departmentID)

                formID = System.Guid.NewGuid.ToString
                AssetVisionXAuto.Facade.AfBizManage.CreateH_AV_ASSET_MOVEInfo( _
                    currentDate, _
                    taskRow.FUNCTIONARY, _
                    currentDate, _
                    taskRow.FUNCTIONARY, _
                    True, _
                    String.Empty, _
                    Facade.OpBizManage.GetAutoMoveFormCode(False, taskRow.LOCATION_ID), _
                    AssetVisionXAuto.Decls.CIVALUE_FORM_STATUS_SUBMIT, _
                    toDepartmentRow.DEPARTMENT_ID, _
                    formID, _
                    taskRow.FUNCTIONARY, _
                    True, _
                    String.Empty, _
                    taskRow.TASK_ID, _
                    toDepartmentRow.PRINCIPAL, _
                    True, _
                    String.Empty, _
                    toLocationRow.DEPARTMENT_ID, _
                    taskRow.PRINCIPAL, _
                    taskRow.LOCATION_ID)

                movingDepartmentAssets = CType(movingDepartmentAssetLists(departmentID), ArrayList)

                moveDtlList.Clear()
                For Each resultRow In movingDepartmentAssets
                    moveDtlList.AddNewH_AV_ASSET_MOVE_DTLRow( _
                        resultRow.ASSET_ID, _
                        Guid.NewGuid.ToString, _
                        formID)

                Next

                AssetVisionXAuto.Facade.AfBizManage.SaveBatchH_AV_ASSET_MOVE_DTLData(moveDtlList)

                Facade.OpBizManage.ExecuteMove(formID, True)

            Next

            If maybeLostAssets.Count > 0 Then

                Dim functionaryCondition As New AssetVisionXAuto.Facade.AfXV.ConditionOfXV_M_AV_STAFF(XL.DB.Utils.Condition.LogicOperators.Logic_And)
                functionaryCondition.Add(AfXV.XV_M_AV_STAFFColumns.STAFF_IDColumn, "=", taskRow.FUNCTIONARY)
                Dim functionaryRow As AssetVisionXAuto.FTs.FT_XV_M_AV_STAFFRow = _
                    AssetVisionXAuto.Facade.AfXV.GetXV_M_AV_STAFFRow(functionaryCondition)

                formID = System.Guid.NewGuid.ToString

                AssetVisionXAuto.Facade.AfBizManage.CreateH_AV_ASSET_REMOVEInfo( _
                    currentDate, _
                    taskRow.FUNCTIONARY, _
                    functionaryRow.DEPARTMENT_ID, _
                    Decls.DEFAULT_CI_VALUE_ELIMINATE_WAY_MAYBE_LOST, _
                    currentDate, _
                    functionaryRow.RUNNER, _
                    True, _
                    String.Empty, _
                    Facade.OpBizManage.GetAutoRemoveFormCode( _
                        False, _
                        Decls.DEFAULT_CI_VALUE_ELIMINATE_WAY_MAYBE_LOST, _
                        functionaryRow.PRINCIPAL), _
                    AssetVisionXAuto.Decls.CIVALUE_FORM_STATUS_SUBMIT, _
                    taskRow.LOCATION_ID, _
                    functionaryRow.PRINCIPAL, _
                    True, _
                    String.Empty, _
                    formID, _
                    taskRow.TASK_ID)


                Dim removeDtlList As New AssetVisionXAuto.FTs.FT_H_AV_ASSET_REMOVE_DTL
                Dim removeDtlRow As AssetVisionXAuto.FTs.FT_H_AV_ASSET_REMOVE_DTLRow

                '生成盘亏退出数据 并执行
                For Each resultRow In maybeLostAssets

                    removeDtlRow = removeDtlList.NewH_AV_ASSET_REMOVE_DTLRow
                    removeDtlList.AddH_AV_ASSET_REMOVE_DTLRow(removeDtlRow)
                    removeDtlRow.DETAIL_ID = Guid.NewGuid.ToString
                    removeDtlRow.ASSET_ID = resultRow.ASSET_ID
                    removeDtlRow.FORM_ID = formID

                Next

                AssetVisionXAuto.Facade.AfBizManage.SaveBatchH_AV_ASSET_REMOVE_DTLData(removeDtlList)

                Facade.OpBizManage.ExecuteRemove(formID)

            End If

            AssetVisionXAuto.Facade.AfBizInventory.ReviseT_AV_INVENTORY_TASKRow( _
                taskID, _
                AfBizInventory.T_AV_INVENTORY_TASKColumns.INVENTORY_STATUSColumn, _
                AssetVisionXAuto.Decls.CIVALUE_INVENTORY_STATUS_COMPLETED)

        End Sub


        Public Shared Sub FillOverDuePlanList()

        End Sub
    End Class

End Namespace
